/*
 *  This file is part of AtlasMapper server and clients.
 *
 *  Copyright (C) 2012 Australian Institute of Marine Science
 *
 *  Contact: Gael Lafond <g.lafond@aims.org.au>
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package au.gov.aims.metadatagenerator.wkt;

import java.util.ArrayList;
import java.util.List;

// POLYGON ((30 10, 40 40, 20 40, 10 20, 30 10))
// POLYGON ((35 10, 45 45, 15 40, 10 20, 35 10), (20 30, 35 35, 30 20, 20 30))
public class WktPolygon extends WktObject {
	private List<WktPolygonPart> parts;

	public WktPolygon() {
		this.parts = new ArrayList<WktPolygonPart>();
	}

	public void addPart(WktPolygonPart part) {
		if (part != null && !part.isEmpty()) {
			this.parts.add(part);
			this.updateBound(part);
		}
	}

	public boolean isEmpty() {
		return this.parts.isEmpty();
	}

	@Override
	public String toString() {
		StringBuilder sb = new StringBuilder();
		sb.append("POLYGON (");
		boolean first = true;
		for (WktPolygonPart part : this.parts) {
			if (!first) {
				sb.append(", ");
			}
			sb.append(part.toString());
			first = false;
		}
		sb.append(")");
		return sb.toString();
	}

	/**
	 * This method return a list Linear Ring, usable in a MEST record.
	 * NOTE: Some polygons has to be represented by multiple Linear Ring.
	 * @return
	 */
	public List<String> toLinearRing() {
		List<String> linearRings = new ArrayList<String>();

		for (WktPolygonPart part : this.parts) {
			linearRings.addAll(part.toLinearRing());
		}

		return linearRings;
	}

	public static class WktPolygonPart extends WktObject {
		private List<WktPoint> points;

		public WktPolygonPart() {
			this.points = new ArrayList<WktPoint>();
		}

		public void addPoint(WktPoint point) {
			if (point != null && !point.isEmpty()) {
				this.points.add(point);
				this.updateBound(point);
			}
		}

		public boolean isEmpty() {
			return this.points.isEmpty();
		}

		@Override
		public String toString() {
			StringBuilder sb = new StringBuilder();
			sb.append("(");
			boolean first = true;
			for (WktPoint point : this.points) {
				if (!first) {
					sb.append(", ");
				}
				sb.append(point.getLon()).append(" ").append(point.getLat());
				first = false;
			}
			sb.append(")");
			return sb.toString();
		}

		public List<String> toLinearRing() {
			List<String> linearRings = new ArrayList<String>();

			StringBuilder sb = new StringBuilder();
			boolean first = true;
			for (WktPoint point : this.points) {
				if (!first) {
					sb.append(" ");
				}

				sb.append(this.decimalFormat.format(point.getLon()))
						.append(" ")
						.append(this.decimalFormat.format(point.getLat()));

				first = false;
			}
			linearRings.add(sb.toString());

			return linearRings;
		}
	}
}
